from direct.showbase.DirectObject import DirectObject
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from client.gamestates.gamestatemanager import GameStateManager
from client.gui.guimanager import GuiManager
from client.utils.inputmanager import InputManager
from panda3d.bullet import BulletWorld, BulletDebugNode
from panda3d.core import AmbientLight, DirectionalLight, LightAttrib, Vec4, Vec3
from client.networking.networkmanager import NetworkManager
from panda3d.core import ConfigVariableBool
from direct.filter.CommonFilters import CommonFilters
from client.gamestates.staterunningsession import Role


class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        # Debugging
        self.setFrameRateMeter(False)
        ##self.setup_bullet_debug()

        #ConfigVariableString('text-quality-level', 'best')


        # Disable the camera trackball controls.
        self.disableMouse()

        # init bullet physic world
        self.physicWorld = BulletWorld()

        # init lighting
        self.setup_lights()

        # set default cam view
        self.camCenter = self.render.attachNewNode("CamCenter")
        self.camera.reparentTo(self.camCenter)
        self.camera.setPos(0, -9, 25)
        # self.camera.lookAt(self.camCenter)
        self.camera.setHpr(0, -70, 0)

        # init managers
        self.networkmanager = NetworkManager()
        self.guimanager = GuiManager()
        self.gamestatemanager = GameStateManager()
        self.gamestatemanager.demand("MainMenu")
        self.inputmanager = InputManager()

        #self.guimanager.create_runningsession(Role.ATTACKER)

        # setup exit func
        self.exitFunc = self.exit_func

        # init gameloop
        self.gameTask = self.taskMgr.add(self.game_loop, "game_loop")

    # THE MAIN GAMELOOP
    def game_loop(self, task):
        # get dt
        dt = globalClock.getDt()

        # update network
        self.networkmanager.update(dt)

        # update bullet physic
        self.physicWorld.doPhysics(dt)

         # update game
        self.inputmanager.update(dt)
        self.gamestatemanager.updateActiveState(dt)
        self.guimanager.update(dt)

        # Since every return is Task.cont, the task will loop infinitely
        return Task.cont

    def setup_lights(self):
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.2, .2, .2, 1))
        self.render.setLight(self.render.attachNewNode(ambientLight))

        #directionalLight = DirectionalLight("directionalLight")
        #directionalLight.setColor(Vec4(.2, .2, .2, 1))
        #directionalLight.setShadowCaster(True, 512, 512)
        #directionalLight.showFrustum()
        #self.render.setLight(self.render.attachNewNode(directionalLight))

        self.render.setShaderAuto()

    def setup_bullet_debug(self):
        debugNode = BulletDebugNode('Debug')
        debugNode.showWireframe(True)
        debugNode.showConstraints(True)
        debugNode.showBoundingBoxes(True)
        debugNode.showNormals(True)
        debugNP = self.render.attachNewNode(debugNode)
        debugNP.show()
        self.physicWorld.setDebugNode(debugNP.node())

    def exit_func(self):
        self.networkmanager.close_network()


app = Game()
app.run()
